<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script>
var callbackFunctionTest = internals.callbackFunctionTest();

test(function() {
    var callback1 = function(msg1, msg2) {
        return msg1 + ', ' + msg2;
    };
    assert_equals(callbackFunctionTest.testCallback(callback1, 'hello', 'world'), 'SUCCESS: hello, world');

    var callback2 = function(msg1, msg2) {
        return msg1 + msg1 + ' ' + msg2 + msg2;
    };
    assert_equals(callbackFunctionTest.testCallback(callback2, 'hello', 'world'), 'SUCCESS: hellohello worldworld');
}, 'Callback function which takes two strings');

test(function() {
    var divElement = document.createElement('div');
    var addInnerHTML = function(d) {
        d.innerHTML = 'hello';
    };
    callbackFunctionTest.testInterfaceCallback(addInnerHTML, divElement);
    assert_equals(divElement.innerHTML, 'hello');
}, 'Callback function which takes a interface');

test(function() {
    var callback = function() {
        assert_equals(this, callbackFunctionTest);
    };
    callbackFunctionTest.testReceiverObjectCallback(callback);
}, 'Callback function which takes receiver object');

test(function() {
    var squareStringNumbers = function(numbers) {
        return numbers.map(n => (n * n).toString());
    };
    var results = callbackFunctionTest.testSequenceCallback(squareStringNumbers, [1, 2, 3]);
    assert_equals(3, results.length);
    assert_equals('1', results[0]);
    assert_equals('4', results[1]);
    assert_equals('9', results[2]);
}, 'Callback function which takes a number sequence');

test(function() {
  var callback = function(enum_value) {
    assert_equals(enum_value, 'foo');
  };
  callbackFunctionTest.testEnumCallback(callback, 'foo');
}, 'Callback function which takes an enum value');

test(function() {
    assert_throws_js(TypeError, function() {
        callbackFunctionTest.testCallback(null, 'hello', 'world');
    });
    assert_throws_js(TypeError, function() {
        callbackFunctionTest.testCallback({}, 'hello', 'world');
    });
    assert_throws_js(TypeError, function() {
        callbackFunctionTest.testCallback(1, 'hello', 'world');
    });
}, 'Passing non-callable values should throw a TypeError');

test(function() {
  assert_equals(callbackFunctionTest.testNullableCallback(null, 'hello', 'world'), 'Empty callback');
}, 'Passing null to nullable callback argument');
</script>
